using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using System.IO.Ports;
using System.Text;

#if MINI
using SecretLabs.NETMF.Hardware.NetduinoMini;
#else
using SecretLabs.NETMF.Hardware.Netduino;
#endif

namespace codebase
{
    public class windowTerminal: UI.Window
    {
        UI.Frame termFrame;
        UI.Frame optionsFrame;

        UI.ListBox termList;
        UI.Button termSUp;
        UI.Button termSDown;
        UI.Button termUse;

        UI.Button termActive;
        UI.Button termRead;
        UI.Button termListClear;
        public UI.Button termSend;

        UI.Frame scriptFrame;
        UI.Button termSaveScript;
        UI.Button termUseScript;
        UI.Button termSetScript;

        UI.Frame sdFrame;
        UI.Button termUseSD;
        UI.Button termSaveSD;
        UI.Button termDelSD;

        UI.Frame dataFrame;
        UI.RadioButton termMode;
        UI.Label termData;

        UI.Frame bottomFrame;
        UI.Button voltDTR;
        UI.Button voltRTS;

        UI.Button termBack;

        SerialMonitor mon;
        Terminal term;

        public windowTerminal(UI.WindowManager manager, SerialMonitor monitor)
        {
            Initialize(manager, monitor);
        }

        public void Initialize(UI.WindowManager manager, SerialMonitor monitor)
        {
            base.Initialize(manager, 0, 0);

            mon = monitor;
            term = mon.terminal;

            FullScreen = true;
            Text = "Terminal";
            Gradient = true;

            termFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 1, 2);
            termFrame.Width = cX(Parent.screen.Width / Parent.screen.CharacterWidth - 2);
            termFrame.Height = cY(10);
            termFrame.Text = "Input/Output";

            optionsFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 1, 13);
            optionsFrame.Width = cX(8);
            optionsFrame.Height = cY(13);
            optionsFrame.Text = "Func.";
            
            termList = (UI.ListBox)Add(UI.Window.ControlTypes.ListBox, 1, 3);
            termList.Width = cX(29);
            termList.Height = cY(9);

            termSUp = (UI.Button)Add(UI.Window.ControlTypes.Button, 30, 3);
            termSUp.Text = "\n < \n";
            termSUp.Released += new UI.Button.ButtonReleasedDelegate(termSUp_Pressed);

            termSDown = (UI.Button)Add(UI.Window.ControlTypes.Button, 30, 6);
            termSDown.Text = "\n > \n";
            termSDown.Released += new UI.Button.ButtonReleasedDelegate(termSDown_Pressed);

            termUse = (UI.Button)Add(UI.Window.ControlTypes.Button, 30, 9);
            termUse.Text = "\n ! \n";
            termUse.isStateButton = true;
            termUse.isPressed = true;

            termActive = (UI.Button)Add(UI.Window.ControlTypes.Button, 1, 14);
            termActive.Text = "\n Active \n";
            termActive.isStateButton = true;
            termActive.isPressed = term.IsOpen();
            termActive.Pressed += new UI.Button.ButtonPressedDelegate(termActive_Released);

            termListClear = (UI.Button)Add(UI.Window.ControlTypes.Button, 1, 17);
            termListClear.Text = "\n Clear  \n";
            termListClear.Released += new UI.Button.ButtonReleasedDelegate(termListClear_Released);

            termRead = (UI.Button)Add(UI.Window.ControlTypes.Button, 1, 20);
            termRead.Text = "\n Read   \n";
            termRead.Released += new UI.Button.ButtonReleasedDelegate(termRead_Released);

            termSend = (UI.Button)Add(UI.Window.ControlTypes.Button, 1, 23);
            termSend.Text = "\n Send   \n";
            termSend.Released += new UI.Button.ButtonReleasedDelegate(termSend_Released);

            dataFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 25, 24);
            dataFrame.Width = cX(8);
            dataFrame.Height = cY(4);
            dataFrame.Text = "Format";

            termMode = (UI.RadioButton)Add(UI.Window.ControlTypes.RadioButton, 25, 25);
            termMode.updateLabels(new string[] { "HEX", "DEC", "ASCII" });
            termMode.Index = 2;
            termMode.SelectedIndexChanged += new UI.RadioButton.SelectedIndexChangedDelegate(termMode_SelectedIndexChanged);

            scriptFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 20, 13);
            scriptFrame.Width = cX(6);
            scriptFrame.Height = cY(10);
            scriptFrame.Text = "Script";

            termUseScript = (UI.Button)Add(UI.Window.ControlTypes.Button, 20, 14);
            termUseScript.Text =                                                    "\n Use  \n";
            termUseScript.isStateButton = true;

            termSetScript = (UI.Button)Add(UI.Window.ControlTypes.Button, 20, 17);
            termSetScript.Text =                                                    "\n Load \n";

            termSaveScript = (UI.Button)Add(UI.Window.ControlTypes.Button, 20, 20);
            termSaveScript.Text =                                                   "\n Save \n";

            sdFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 27, 13);
            sdFrame.Width = cX(6);
            sdFrame.Height = cY(10);
            sdFrame.Text = "SD";

            termUseSD = (UI.Button)Add(UI.Window.ControlTypes.Button, 27, 14);
            termUseSD.Text = "\n Use  \n";
            termUseSD.isStateButton = true;

            termSaveSD = (UI.Button)Add(UI.Window.ControlTypes.Button, 27, 17);
            termSaveSD.Text = "\n Save \n";

            termDelSD = (UI.Button)Add(UI.Window.ControlTypes.Button, 27, 20);
            termDelSD.Text = "\n Del  \n";

            bottomFrame = (UI.Frame)Add(UI.Window.ControlTypes.Frame, 1, 36);
            bottomFrame.Height = cY(3);
            bottomFrame.Width = cX(Parent.screen.Width / Parent.screen.CharacterWidth - 2);

            termData = (UI.Label)Add(UI.Window.ControlTypes.Label, 24, 37);
            termData.Text = "No Conn.";

            voltDTR = (UI.Button)Add(UI.Window.ControlTypes.Button, 7, 36);
            voltDTR.Text = "\n DTR \n";
            voltDTR.isStateButton = true;
            voltDTR.isPressed = true;
            voltDTR.Pressed += new UI.Button.ButtonPressedDelegate(voltDTR_Released);

            voltRTS = (UI.Button)Add(UI.Window.ControlTypes.Button, 12, 36);
            voltRTS.Text = "\n RTS \n";
            voltRTS.isStateButton = true;
            voltRTS.isPressed = true;
            voltRTS.Pressed += new UI.Button.ButtonPressedDelegate(voltRTS_Released);

            termBack = (UI.Button)Add(UI.Window.ControlTypes.Button, 1, 36);
            termBack.Text = "\n Back \n";
            termBack.Released += new UI.Button.ButtonReleasedDelegate(back_Pressed);

            term.MaxResponseLength = (termList.Width / Parent.screen.CharacterWidth) - 3;
            term.TerminalData += new Terminal.TerminalDataDelegate(term_TerminalData);
            term.TerminalByteCount += new Terminal.TerminalCountDelegate(term_TerminalByteCount);
        }

        void term_TerminalByteCount(int count)
        {
            updateByteCounter(count);
        }

        void term_TerminalData(string data,Terminal.Direction dir)
        {
            if (termUse.isPressed)
            {
                termList.addItem(dir == Terminal.Direction.In?"<" + data:">" + data);
                termList.Refresh();
            }
        }

        void voltRTS_Released(UI.Button btn)
        {
            btn.isPressed = true;
            btn.Refresh();
        }

        void voltDTR_Released(UI.Button btn)
        {
            btn.isPressed = true;
            btn.Refresh();
        }

        void termSend_Released(UI.Button btn)
        {
            windowInput input = new windowInput(Parent, mon);
            input.Show(Settings.Inputs.Send, mon.settings.lastSendText,true);
        }

        public void updateByteCounter(int count)
        {
            if (Visible)
            {   
                termData.Clear(9);

                if (term.IsOpen())
                {
                    termData.Text = count.ToString() + " Bytes";
                }
                else
                {
                    termData.Text = "No Conn.";
                }
                
                termData.Refresh();
            }
        }

        void back_Pressed(UI.Button btn)
        {
            mon.formMain.Visible = true;

            term.TerminalData -= term_TerminalData;
            term.TerminalByteCount -= term_TerminalByteCount;

            Parent.Remove(this);
            
            Parent.Redraw();
        }

        void termRead_Released(UI.Button btn)
        {
            term.readSerialData(true);
        }

        void termListClear_Released(UI.Button btn)
        {
            termList.clear();
            termList.Redraw();
        }

        void termMode_SelectedIndexChanged(int idx)
        {
            term.answerFormat = (Terminal.Formats)idx;
        }

        void termActive_Released(UI.Button btn)
        {
            if (termActive.isPressed)
            {
                if (term.IsOpen()) term.Close();

                term.setBaudRate(mon.settings.BaudRate);
                term.setParity(mon.settings.Parity);
                term.setDataBits(mon.settings.DataBits);
                term.setStopBits(mon.settings.StopBits);

                term.Open();

                if (!term.IsOpen())
                {
                    termActive.isPressed = false;
                    termActive.Refresh();
                }
            }
            else
            {
                if (term.IsOpen())
                {
                    term.Close();
                }
            }

            updateByteCounter(0);
        }

        void termSUp_Pressed(UI.Button btn)
        {
            termList.scrollUp();
            termList.Refresh();
        }

        void termSDown_Pressed(UI.Button btn)
        {
            termList.scrollDown();
            termList.Refresh();
        }
    }
}
